package org.jeecg.modules.room.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.FillRuleConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.room.entity.RoomBookInfo;
import org.jeecg.modules.room.entity.RoomBookInfoMx;
import org.jeecg.modules.room.entity.RoomBookReceipt;
import org.jeecg.modules.room.entity.RoomType;
import org.jeecg.modules.room.mapper.RoomBookInfoMapper;
import org.jeecg.modules.room.mapper.RoomBookInfoMxMapper;
import org.jeecg.modules.room.service.*;
import org.jeecg.modules.room.vo.RoomFpStatusVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @Description: 预定单主信息
 * @Author: jeecg-boot
 * @Date:   2023-12-19
 * @Version: V1.0
 */
@Service
public class RoomBookInfoServiceImpl extends ServiceImpl<RoomBookInfoMapper, RoomBookInfo> implements IRoomBookInfoService {

    @Autowired
    private RoomBookInfoMapper roomBookInfoMapper;
    @Autowired
    private RoomBookInfoMxMapper roomBookInfoMxMapper;
    @Autowired
    private IRoomInfoService roomInfoService;
    @Autowired
    private IRoomTypeService roomTypeService;
    @Autowired
    private IRoomBookReceiptService roomBookReceiptService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveMain(RoomBookInfo roomBookInfo, List<RoomBookInfoMx> roomBookInfoMxList) {

        try {
            roomBookInfo.setBookStatus("00");
            JSONObject formData = new JSONObject();
            formData.put("prefix","YD");
            roomBookInfo.setBookCode((String) FillRuleUtil.executeRule(FillRuleConstant.ORDER,formData));
            roomBookInfoMapper.insert(roomBookInfo);
            if(roomBookInfoMxList == null || roomBookInfoMxList.size() == 0)
            {
                throw new JeecgBootException("预订单明细信息不能为空!");
            }
            else {
                for (RoomBookInfoMx entity : roomBookInfoMxList) {
                    //外键设置
                    int usableNum = roomInfoService.selectUsableRoomNum(entity.getRoomTypeCode(), roomBookInfo.getDateArrival(), roomBookInfo.getDateDeparture());
                    if (usableNum < entity.getBookRoomNum()) {
                        RoomType roomType = roomTypeService.getOne(new QueryWrapper<RoomType>().eq("room_type_code", entity.getRoomTypeCode()));
                        throw new JeecgBootException(roomBookInfo.getDateArrival() + "至" + roomBookInfo.getDateDeparture() + roomType.getRoomTypeName() + "房间余量不足，最大可预约房间数" + usableNum);
                    }
                    entity.setBookCode(roomBookInfo.getBookCode());
                    roomBookInfoMxMapper.insert(entity);
                }
            }
        }
        catch (Exception e){
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMain(RoomBookInfo roomBookInfo,List<RoomBookInfoMx> roomBookInfoMxList) {

        try {
            roomBookInfoMapper.updateById(roomBookInfo);

            //1.先删除子表数据
            roomBookInfoMxMapper.deleteByMainId(roomBookInfo.getBookCode());

            //2.子表数据重新插入
            if(roomBookInfoMxList == null || roomBookInfoMxList.size() == 0)
            {
                throw new JeecgBootException("预订单明细信息不能为空!");
            }
            else {
                for (RoomBookInfoMx entity : roomBookInfoMxList) {
                    //外键设置
                    int usableNum = roomInfoService.selectUsableRoomNum(entity.getRoomTypeCode(), roomBookInfo.getDateArrival(), roomBookInfo.getDateDeparture());
                    if (usableNum < entity.getBookRoomNum()) {
                        RoomType roomType = roomTypeService.getOne(new QueryWrapper<RoomType>().eq("room_type_code", entity.getRoomTypeCode()));
                        throw new JeecgBootException(roomBookInfo.getDateArrival() + "至" + roomBookInfo.getDateDeparture() + roomType.getRoomTypeName() + "房间余量不足，最大可预约房间数" + usableNum);
                    }
                    entity.setBookCode(roomBookInfo.getBookCode());
                    roomBookInfoMxMapper.insert(entity);
                }
            }
        }
        catch (Exception e){
            throw e;
        }
    }

    /**
     *
     * @param id
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delMain(String id) {
        try {
            RoomBookInfo roomBookInfo = this.baseMapper.selectById(id);
            //查询是否完成退款
            QueryWrapper<RoomBookReceipt> queryWrapper = new  QueryWrapper<RoomBookReceipt>();
            queryWrapper.select("sum(receipt_amt) as receipt_amt");
            queryWrapper.eq("book_code",roomBookInfo.getBookCode());
            RoomBookReceipt roomBookReceipt = roomBookReceiptService.getOne(queryWrapper);

            long cnt = roomBookReceiptService.count(new QueryWrapper<RoomBookReceipt>().eq("book_code",roomBookInfo.getBookCode()).eq("audit_flag","1"));
            if (!roomBookInfo.getBookStatus().equals("00")) {
                throw new JeecgBootException("预定单号:" + roomBookInfo.getBookCode() + "非未确认状态不可删除!");
            }
            else if(roomBookReceipt != null && roomBookReceipt.getReceiptAmt() != null && roomBookReceipt.getReceiptAmt() != 0){
                throw new JeecgBootException("预定单号:" + roomBookInfo.getBookCode() + "未完成退款不可删除订单!");
            }
            else if(cnt > 0){ //是否过夜审，过夜审不能删除，只能取消订单，执行取消订单操作
                //执行取消订单函数
                cancelBook(roomBookInfo.getBookCode());
            }
            else {
                roomBookInfoMxMapper.deleteByMainId(roomBookInfo.getBookCode());
                roomBookInfoMapper.deleteById(id);

                //删除收款
                roomBookReceiptService.remove(new QueryWrapper<RoomBookReceipt>().eq("book_code",roomBookInfo.getBookCode()));
            }
        }
        catch (Exception e){
            throw e;
        }
    }

    /**
     * 批量删除
     * @param idList
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void  delBatchMain(Collection<? extends Serializable> idList) {
        try {
            for (Serializable id : idList) {
                RoomBookInfo roomBookInfo = this.baseMapper.selectById(id);

                //查询是否完成退款
                QueryWrapper<RoomBookReceipt> queryWrapper = new  QueryWrapper<RoomBookReceipt>();
                queryWrapper.select("sum(receipt_amt) as receipt_amt");
                queryWrapper.eq("book_code",roomBookInfo.getBookCode());
                RoomBookReceipt roomBookReceipt = roomBookReceiptService.getOne(queryWrapper);

                long cnt = roomBookReceiptService.count(new QueryWrapper<RoomBookReceipt>().eq("book_code",roomBookInfo.getBookCode()).eq("audit_flag","1"));
                if (!roomBookInfo.getBookStatus().equals("00")) {
                    throw new JeecgBootException("预定单号:" + roomBookInfo.getBookCode() + "非未确认状态不可删除!");
                }
                else if(roomBookReceipt != null && roomBookReceipt.getReceiptAmt() != null && roomBookReceipt.getReceiptAmt() != 0){
                    throw new JeecgBootException("预定单号:" + roomBookInfo.getBookCode()+ "未完成退款不可删除订单!");
                }
                else if(cnt > 0){ //是否过夜审，过夜审不能删除，只能取消订单，执行取消订单操作
                    //执行取消订单函数
                    cancelBook(roomBookInfo.getBookCode());
                }
                else {
                    roomBookInfoMxMapper.deleteByMainId(roomBookInfo.getBookCode());
                    roomBookInfoMapper.deleteById(id);

                    //删除收款
                    roomBookReceiptService.remove(new QueryWrapper<RoomBookReceipt>().eq("book_code",roomBookInfo.getBookCode()));
                }
            }
        }
        catch (Exception e){
            throw e;
        }
    }

    @Override
    public IPage<RoomBookInfo> selectBookInfoList(IPage<RoomBookInfo> page, Wrapper<RoomBookInfo> queryWrapper) {
        return roomBookInfoMapper.selectBookInfoList(page,queryWrapper);
    }

    /**
     * 查询分配房间情况
     * @param bookCode
     * @return
     */
    @Override
    public List<RoomFpStatusVo> selectFpStatus(String bookCode) {
        return roomBookInfoMapper.selectFpStatus(bookCode);
    }

    /**
     * 取消订单
     * 逻辑 1、是否过夜审，过夜审不能删除，只能取消
     * 2、每天夜审时将当日应到未到并且未收款/收款后全额退款的删除
     * 3、每天夜审时将当日应到未到并且已收款金额大于0的不变
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelBook(String bookCodes) {

        try {
            List<String> bookCodeArr = Arrays.asList(bookCodes.split(","));
            for(String bookCode : bookCodeArr) {
                //只有00 未确认状态可以取消订单
                RoomBookInfo roomBookInfo = roomBookInfoMapper.selectOne(new QueryWrapper<RoomBookInfo>().eq("book_code",bookCode));

                //查询是否完成退款
                QueryWrapper<RoomBookReceipt> queryWrapper = new  QueryWrapper<RoomBookReceipt>();
                queryWrapper.select("sum(receipt_amt) as receipt_amt");
                queryWrapper.eq("book_code",roomBookInfo.getBookCode());
                RoomBookReceipt roomBookReceipt = roomBookReceiptService.getOne(queryWrapper);

                if (!roomBookInfo.getBookStatus().equals("00")) {
                    throw new JeecgBootException("预定单号:" + roomBookInfo.getBookCode()+ "非未确认状态不可取消订单!");
                } else if (roomBookReceipt.getReceiptAmt() != null && roomBookReceipt.getReceiptAmt() != 0) {
                    throw new JeecgBootException("预定单号:" + roomBookInfo.getBookCode()+ "未完成退款不可取消未完成退款订单!");
                } else {
                    //修改状态
                    roomBookInfo.setBookStatus("99");
                    roomBookInfoMapper.updateById(roomBookInfo);
                }
            }
        }
        catch (Exception e){
            throw e;
        }
    }

    /**
     * 确认订单
     * @param bookCodes
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmBook(String bookCodes) {

        try {
            List<String> bookCodeArr = Arrays.asList(bookCodes.split(","));
            for(String bookCode : bookCodeArr) {
                RoomBookInfo roomBookInfo = roomBookInfoMapper.selectOne(new QueryWrapper<RoomBookInfo>().eq("book_code",bookCode));
                //00 未确认状态可以确认订单
                if (!roomBookInfo.getBookStatus().equals("00")) {
                    throw new JeecgBootException("预定单号:" + roomBookInfo.getBookCode()+ "非未确认状态不可确认订单!");
                } else {
                    //修改状态
                    roomBookInfo.setBookStatus("10");
                    roomBookInfoMapper.updateById(roomBookInfo);
                }
            }
        }
        catch (Exception e){
            throw e;
        }
    }

    /**
     * 撤销确认
     * @param bookCodes
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unConfirmBook(String bookCodes) {

        try {
            List<String> bookCodeArr = Arrays.asList(bookCodes.split(","));
            for(String bookCode : bookCodeArr) {
                //10 确认状态可以撤销确认订单
                RoomBookInfo roomBookInfo = roomBookInfoMapper.selectOne(new QueryWrapper<RoomBookInfo>().eq("book_code",bookCode));
                if (!roomBookInfo.getBookStatus().equals("10")) {
                    throw new JeecgBootException("预定单号:" + roomBookInfo.getBookCode()+ "非确认状态不可撤销确认订单!");
                } else {
                    //修改状态
                    roomBookInfo.setBookStatus("00");
                    roomBookInfoMapper.updateById(roomBookInfo);
                }
            }
        }
        catch (Exception e){
            throw e;
        }
    }

    @Override
    public List<Map> selectBookByDate() {
        return roomBookInfoMapper.selectBookByDate();
    }
}
